package com.ddzj.scaffold.utils;

import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.engines.SM4Engine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Hex;

/**
 * @Author:yangzibo
 * @CreateTime:2024-05-12 19:40
 * @Description:
 * @Version:1.0
 **/
public class SM4Utils {
    public static String encrypt(String plaintext, byte[] key) {
        try {
            BlockCipher cipher = new CBCBlockCipher(new SM4Engine());
            BufferedBlockCipher bbc = new BufferedBlockCipher(cipher);

            byte[] keyBytes = key;
            KeyParameter keyParam = new KeyParameter(keyBytes);

            bbc.init(true, keyParam);

            byte[] input = plaintext.getBytes("UTF-8");
            byte[] output = new byte[bbc.getOutputSize(input.length)];

            int len = bbc.processBytes(input, 0, input.length, output, 0);
            bbc.doFinal(output, len);

            return Hex.toHexString(output);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String decrypt(String ciphertext, byte[] key) {
        try {
            BlockCipher cipher = new CBCBlockCipher(new SM4Engine());
            BufferedBlockCipher bbc = new BufferedBlockCipher(cipher);

            byte[] keyBytes = key;
            KeyParameter keyParam = new KeyParameter(keyBytes);

            bbc.init(false, keyParam);

            byte[] input = Hex.decode(ciphertext);
            byte[] output = new byte[bbc.getOutputSize(input.length)];

            int len = bbc.processBytes(input, 0, input.length, output, 0);
            bbc.doFinal(output, len);

            return new String(output, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) {
        String plaintext = "Hello, SM4!";
        byte[] key = Hex.decode("0123456789abcdeffedcba9876543210");

        String ciphertext = encrypt(plaintext, key);
        System.out.println("Ciphertext: " + ciphertext);

        String decryptedText = decrypt(ciphertext, key);
        System.out.println("Decrypted text: " + decryptedText);
    }
}
